package summer.codegenerator.service.base;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javax.persistence.Id;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Order;
import org.springframework.stereotype.Service;

import summer.codegenerator.persistence.hibernate.base.BaseDao;
import summer.codegenerator.persistence.hibernate.base.tool.Pagination;
import summer.codegenerator.persistence.hibernate.base.tool.Sort;
import summer.codegenerator.persistence.hibernate.base.tool.WhereClause;

import com.alibaba.fastjson.JSONObject;

/**
 * @author Administrator
 *
 */
@Service
public class BaseServiceImpl<T> implements BaseService<T> {

	protected BaseDao<T> baseDao;

	public void setBaseDao(BaseDao<T> baseDao) {
		this.baseDao = baseDao;
	}

	@Override
	public T copyById(Long id) {
		return baseDao.copyById(id);
	}

	@Override
	public void saveClear(T entity) {
		baseDao.save(entity);
	}

	@Override
	public void updateClear(T entity) {
		baseDao.update(entity);
	}

	@Override
	public T save(T entity) throws Exception {
		baseDao.save(entity);
		baseDao.flushThenClear();
		Long id = this.getEntityId(entity);
		return baseDao.copyById(id);
	}

	@Override
	public T update(T entity) throws Exception {
		baseDao.update(entity);
		baseDao.flushThenClear();
		Long id = this.getEntityId(entity);
		return baseDao.copyById(id);
	}

	@Override
	public void delete(T entity) {
		baseDao.delete(entity);
	}

	@Override
	public void delete(Long entityId) {
		baseDao.delete(entityId);
	}

	@Override
	public void delete(List<Long> entityIds) {
		for (Long entityId : entityIds) {
			baseDao.delete(entityId);
		}
	}

	@Override
	public List<T> list(WhereClause whereClause) {
		return baseDao.list(whereClause, null, null);
	}

	@Override
	public List<T> list(WhereClause whereClause, Sort sort) {
		return baseDao.list(whereClause, sort, null);
	}

	@Override
	public List<T> list(WhereClause whereClause, Sort sort, Pagination pagination) {
		return baseDao.list(whereClause, sort, pagination);
	}

	@Override
	public List<T> listByCriteria(JSONObject condition, List<Order> orders, Pagination pagination) {
		return baseDao.listByCriteria(condition, orders, pagination);
	}

	@Override
	public Long countTotal(WhereClause whereClause) {
		return baseDao.countTotal(whereClause);
	}

	@Override
	public Long countTotalByCriteria(JSONObject condition) {
		return baseDao.countTotalByCriteria(condition);
	}

	/**
	 * 重新加载时获取实体标识
	 *
	 * 
	 * @param entity 实体
	 * @return
	 * @author: jiangz
	 * @date: Created on 2019年7月24日 上午11:19:58
	 */
	private Long getEntityId(T entity) {
		Field[] fields = entity.getClass().getDeclaredFields();
		Field idField = null;
		for (Field field : fields) {
			Id clazz = field.getAnnotation(Id.class);
			if (clazz != null) {
				idField = field;
				break;
			}
		}
		Long id = null;
		try {
			Method idGetMethod = entity.getClass().getDeclaredMethod("get" + StringUtils.capitalize(idField.getName()));
			id = (Long) idGetMethod.invoke(entity);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return id;
	}

	@Override
	public void removeAll(List<T> list) {
		for (T t : list) {
			this.remove(t);
		}

	}

	@Override
	public void remove(T entity) {
		baseDao.delete(entity);
	}
}
